/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ua.yandex.collections;

import java.util.Arrays;

public class MyArrayList implements MyList {

    private static final int Ten = 10;
    private Object[] elemMass;
    private int size;

    public MyArrayList() {
        //this.elemMass = null;
        this.elemMass = new Object[Ten];
        this.size = 0;
        // Arrays.fill(this.elemMass,(Object)null);
    }

    public MyArrayList(int initialCapacity) {
        this.elemMass = new Object[initialCapacity];
        Arrays.fill(this.elemMass, null);
    }

    @Override
    public void add(Object e) {
        this.add(this.size(), e);
    }

    protected boolean badIndex(int index) {

        return index > this.size() - 1 || index < 0;
    }

    @Override
    public void add(int index, Object e) {
        if (index == this.size()) {
            if (this.size() == this.elemMass.length) {
                this.ensureCapacity(Ten);
            }
            this.elemMass[this.size()] = e;
        } else if (index != 0 && badIndex(index)) {
            throw new IllegalArgumentException("Les than list size");
        }
        if (this.isEmpty()) {
            this.elemMass = new Object[1];
            this.elemMass[0] = e;
        } else {
            Object[] temporary = this.toArray();
            if (this.size() == this.elemMass.length) {
                this.ensureCapacity(Ten);
            }
            System.arraycopy(temporary, 0, this.elemMass, 0, index);
            this.elemMass[index] = e;
            System.arraycopy(temporary, index,
                    this.elemMass, index + 1, this.size() - index);
        }
        this.size++;

    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public void addAll(Object[] c) {
        Object[] a = new Object[this.size() + c.length];
        System.arraycopy(this.elemMass, 0, a, 0, this.size());
        System.arraycopy(c, 0, a, this.size(), c.length);
        this.elemMass = a;
        this.size += c.length;
    }

    @Override
    public void addAll(int index, Object[] c) {
        if (badIndex(index)) {
            throw new IllegalArgumentException("Les than list size");
        }
        Object[] a = new Object[this.size() + c.length];
        System.arraycopy(this.elemMass, 0, a, 0, index);
        System.arraycopy(c, 0, a, index, c.length);
        System.arraycopy(this.elemMass, index, a,
                index + c.length, this.size() - index);
        this.elemMass = a;
        this.size += c.length;
    }

    @Override
    public Object get(int index) {
        if (badIndex(index)) {
            throw new IllegalArgumentException("Les than list size");
        }
        return this.elemMass[index];
    }

    @Override
    public Object remove(int index) {
        if (badIndex(index)) {
            throw new IllegalArgumentException("Les than list size");
        }
        Object e = this.elemMass[index];
        for (int i = index; i < this.size() - 1; i++) {
            this.elemMass[i] = this.elemMass[i + 1];
        }

        this.size--;
        return e;
    }

    @Override
    public void set(int index, Object e) {
        if (badIndex(index)) {
            throw new IllegalArgumentException("Les than list size");
        }
        this.elemMass[index] = e;
    }

    @Override
    public int indexOf(Object o) {
        int i = 0;
        if (o == null) {
            while (this.elemMass[i] != null && i < this.size() - 1) {
                i++;
            }
            if (i == this.size() - 1) {
                return -1;
            }
        } else {
            while (!this.elemMass[i].equals(o) && i < this.size() - 1) {
                i++;
            }
            if (i == this.size() - 1) {
                return -1;
            }
        }
        return i;
    }

    @Override
    public void clear() {
        this.elemMass = new Object[0];
        this.size = 0;
    }

    @Override
    public boolean isEmpty() {
        return this.size() == 0;
    }

    @Override
    public Object[] toArray() {
        Object[] a = new Object[this.size()];
        System.arraycopy(this.elemMass, 0, a, 0, this.size());
        return a;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < this.size(); i++) {
            sb.append(this.elemMass[i]);
            sb.append(",");
        }

        return sb.toString();
    }

    public void ensureCapacity(int minCapacity) {
        Object[] b = new Object[this.size() + minCapacity];
        System.arraycopy(this.elemMass, 0, b, 0, this.size());
        this.elemMass = b;
    }
}
